home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume10 / ifp / part06 < prev    next >
Encoding:
Text File  |  1987-07-06  |  54.7 KB  |  2,213 lines

  1. Path: uunet!rs
  2. From: rs@uunet.UU.NET (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v10i039: Interpreted Functional Programming lanuage, Part 06/07
  5. Message-ID: <579@uunet.UU.NET>
  6. Date: 7 Jul 87 23:23:00 GMT
  7. Organization: UUNET Communications Services, Arlington, VA
  8. Lines: 2202
  9. Approved: rs@uunet.uu.net
  10.  
  11. Mod.sources: Volume 10, Number 39
  12. Submitted by: robison@b.cs.uiuc.edu (Arch Robison)
  13. Archive-name: ifp/Part06
  14.  
  15. #! /bin/sh
  16. # This is a shell archive, meaning:
  17. # 1. Remove everything above the #! /bin/sh line.
  18. # 2. Save the resulting text in a file.
  19. # 3. Execute the file with /bin/sh.
  20. # The following files will be created:
  21. #    interp/infun.c
  22. #    interp/inimport.c
  23. #    interp/inob.c
  24. #    interp/inob.h
  25. #    interp/list.c
  26. #    interp/main.c
  27. #    interp/node.c
  28. #    interp/node.h
  29. export PATH; PATH=/bin:$PATH
  30. mkdir interp
  31. if test -f 'interp/infun.c'
  32. then
  33.     echo shar: over-writing existing file "'interp/infun.c'"
  34. fi
  35. cat << \SHAR_EOF > 'interp/infun.c'
  36.  
  37. /****** infun.c *******************************************************/
  38. /**                                                                  **/
  39. /**                    University of Illinois                        **/
  40. /**                                                                  **/
  41. /**                Department of Computer Science                    **/
  42. /**                                                                  **/
  43. /**   Tool: IFP                         Version: 0.5                 **/
  44. /**                                                                  **/
  45. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  46. /**                                                                  **/
  47. /**   Revised by: Arch D. Robison       Date:   Aug 4, 1986          **/
  48. /**                                                                  **/
  49. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  50. /**                            Prof. W. J. Kubitz                    **/
  51. /**                                                                  **/
  52. /**                                                                  **/
  53. /**------------------------------------------------------------------**/
  54. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  55. /**                       All Rights Reserved.                       **/
  56. /**********************************************************************/
  57.  
  58.  
  59. #include <stdio.h>
  60. #include <ctype.h>
  61. #include "struct.h"
  62. #include "node.h"
  63. #include "string.h"
  64. #include "inob.h"
  65.  
  66. /*
  67.  * PATTERN should be 0.  Setting it to 1 enables a parser extension
  68.  * for experimental compiler work.
  69.  */
  70. #define PATTERN 0
  71.  
  72. /*
  73.  * MakeForm
  74.  *
  75.  * If correct, create form with node N and function list Funs.
  76.  *
  77.  * Output
  78.  *      result = 1 if no error, 0 otherwise
  79.  */
  80. boolean MakeForm (Correct,N,Funs,InOut)
  81.    boolean Correct;
  82.    NodePtr N;
  83.    ListPtr Funs;
  84.    ObjectPtr InOut;
  85.    {
  86. #ifdef PARAMBUG        /* cure for CRAY C-compiler bug (see struct.h) */
  87. {
  88.       ListPtr T = Funs;
  89.       NewList (&T,1L);
  90.       Funs = T;
  91. }
  92. #else
  93.       NewList (&Funs,1L); 
  94. #endif
  95.       if (SysError || !Correct) {
  96.      DelLPtr (Funs);
  97.      return 0;
  98.       } else {
  99.      Funs->Val.Tag = NODE;
  100.      Funs->Val.Node = CopyNPtr (N);
  101.      RepTag (InOut,LIST);
  102.      InOut->List = Funs;
  103.      return 1;
  104.       }
  105.    }
  106.  
  107. /*
  108.  * InNext
  109.  *
  110.  * Input next composition, which should be followed by Token.
  111.  *
  112.  * Input
  113.  *      *F = input
  114.  *      End = pointer to MetaPtr to end of list.
  115.  *      Token = token expected.
  116.  *    K = pointer to entry of form being parsed 
  117.  */
  118. boolean InNext (F,End,Token,K,Env)
  119.    InDesc *F;
  120.    MetaPtr *End;
  121.    char *Token;
  122.    FormEntry *K;
  123.    ListPtr Env;
  124.    {
  125.       NewList (*End,1L);
  126.       if (SysError || !InComp (F,&(**End)->Val,Env)) return 0;
  127.       if (!IsTok (F,Token)) {
  128.      char Error [80];
  129.      extern char *sprintf();
  130.      (void) sprintf (Error,"'%s' part of '%s' expected",
  131.              Token,K->FormComment);
  132.      return InError (F,Error);
  133.       }
  134.       *End = &(**End)->Next;
  135.       return 1;
  136.    }
  137.  
  138. /*
  139.  * InPFO
  140.  *
  141.  * Input a PFO.
  142.  *
  143.  * Input
  144.  *     F = input descriptor pointing to 1st token after 1st keyword of form
  145.  *      K = index of form
  146.  *    Env = environment list
  147.  *
  148.  * Output
  149.  *    InOut = form
  150.  */
  151. private boolean InPFO (F,InOut,K,Env)
  152.    register InDesc *F;
  153.    ObjectPtr InOut;
  154.    FormEntry *K;
  155.    ListPtr Env;
  156.    {
  157.       ListPtr R = NIL;
  158.       MetaPtr A = &R;
  159.       boolean Correct;
  160.  
  161.       switch (K-FormTable) {
  162.      case NODE_If:
  163.         Correct = 0;
  164.         if (InNext (F,&A,"THEN",K,Env) && InNext (F,&A,"\0",K,Env))
  165.            if (IsTok (F,"ELSIF")) {
  166.           NewList (A,1L);
  167.           Correct = !SysError && InPFO (F,&(*A)->Val,K,Env);
  168.            } else
  169.           if (IsTok (F,"ELSE")) Correct = InNext (F,&A,"END",K,Env);
  170.           else (void) InError (F,"'ELSE' or 'ELSIF' expected");
  171.         break;
  172.  
  173.      case NODE_Each:
  174.      case NODE_RInsert:
  175.      case NODE_Filter:
  176.         Correct = InNext (F,&A,"END",K,NIL);
  177.         break;
  178.  
  179.      case NODE_While:
  180.         Correct = InNext (F,&A,"DO",K,NIL) && InNext (F,&A,"END",K,NIL);
  181.         break;
  182. #if XDEF
  183.      case NODE_XDef: {
  184.         ListPtr OldEnv = Env;
  185.         Correct = 0;
  186.         NewList (A,1L);
  187.         if (SysError || !InLHS (F,&(*A)->Val,&Env)) break;
  188.         if (!IsTok (F,":=")) (void) InError (F,"':=' expected");
  189.         else {
  190.            A = &(*A)->Next;
  191.            if (!InNext (F,&A,"}",K,OldEnv)) break;
  192.            NewList (A,1L);
  193.            if (InSimple (F,&(*A)->Val,Env)) Correct = 1;
  194.         }
  195.         break;
  196.      }
  197. #endif
  198.      case NODE_C:
  199.         NewList (A,1L);
  200.         if (Correct = !SysError && InObject (F,&(*A)->Val))
  201.            if ((*A)->Val.Tag == BOTTOM) {
  202.           /* Convert #? to #(null) */
  203.           DelLPtr (R);
  204.           R = NIL;
  205.           }
  206.         break;
  207.  
  208.      case NODE_Cons:
  209.         if (!(Correct = IsTok (F,"]"))) {
  210.            while ((Correct = InNext (F,&A,"\0",K,Env)) && IsTok (F,",")) 
  211.           continue;
  212.            if (Correct) 
  213.           if (Correct = IsTok (F,"]"));
  214.           else (void) InError (F,"']' or ',' expected");
  215.         }
  216.         break;
  217.  
  218. #if FETCH
  219.      case NODE_Fetch:
  220. #endif
  221.      case NODE_Out:
  222.         NewList (A,1L);
  223.         Correct = !SysError && InObject (F,&(*A)->Val);
  224.         break;
  225.  
  226.       }
  227.       return MakeForm (Correct,K->FormNode,R,InOut);
  228.    }
  229.  
  230. /*
  231.  * InSelector
  232.  *
  233.  * Input
  234.  *     F = input descriptor pointing to selector
  235.  *
  236.  * Output
  237.  *    InOut = selector PFO
  238.  */
  239. private boolean InSelector (F,InOut)
  240.    register InDesc *F;
  241.    ObjectPtr InOut;
  242.    {
  243.       register ListPtr P;
  244.       long Index = 0;
  245.  
  246.       do 
  247.      Index = 10*Index + (*F->InPtr++) - '0';
  248.       while isdigit (*F->InPtr);
  249.  
  250.       RepTag (InOut,LIST);
  251.       InOut->List = NIL;
  252.       NewList (&InOut->List,2L);
  253.       if (SysError) {
  254.      InOut->Tag = BOTTOM;
  255.      return 0;
  256.       }
  257.       P = InOut->List;
  258.       P->Val.Tag = NODE;
  259.       P->Val.Node = FormTable [NODE_Sel].FormNode;
  260.       P = P->Next;
  261.       P->Val.Tag = INT;
  262.       P->Val.Int = IsTok (F,"r") ? -Index : Index;
  263.       return 1;
  264.    }
  265.  
  266. /*
  267.  * InSimple
  268.  *
  269.  * Read a simple function
  270.  *
  271.  * Output
  272.  *      result = 1 iff error occurs, 0 otherwise
  273.  *      InOut = simple function if no error
  274.  *
  275.  * A SysError may occur, in which case InOut is unchanged.
  276.  */
  277. boolean InSimple (F,InOut,Env)
  278.    InDesc *F;
  279.    ObjectPtr InOut;
  280.    ListPtr Env;
  281.    {
  282.       static char InFirst[] = {     /* First characters of InPrefix */
  283.       'I','E','W','#','[','F','@'
  284. #if FETCH
  285.      ,'^'
  286. #endif
  287. #if XDEF
  288.      ,'{'
  289. #endif
  290.      ,'\0'
  291.       };
  292.       register FormEntry *K;
  293.       extern char *index ();
  294.  
  295.       if (Debug & DebugParse) {
  296.      printf ("InSimple: Env = "); OutList (Env); 
  297.      printf (", F = %s\n",F->InPtr);
  298.       } 
  299.       InBlanks (F);
  300. #ifdef PATTERN
  301.       if (IsTok (F,"!")) return InObject (F,InOut);
  302. #endif
  303.       /* 
  304.        * The "index" lookup below quickly rejects strings which
  305.        * cannot be key words.
  306.        */
  307.       if (NULL != index (InFirst,*F->InPtr)) {
  308.      for (K=FormTable; K < ArrayEnd(FormTable); K++) 
  309.         if (*K->FormInPrefix != '\0' && IsTok (F,K->FormInPrefix))
  310.            return InPFO (F,InOut,K,Env);
  311.       } else
  312.      if (isdigit (*F->InPtr)) 
  313.         return InSelector (F,InOut);
  314.  
  315.       if (!InNode (F,InOut,Env)) 
  316.      return 0;
  317.       else if (InOut->List == NULL) 
  318.      return InError (F,"'/' not a function");
  319.       else
  320.      return 1;
  321.    }
  322.  
  323. /*
  324.  * InComp
  325.  *
  326.  * Input a composition
  327.  */
  328. boolean InComp (F,InOut,Env)
  329.    register InDesc *F;
  330.    ObjectPtr InOut;
  331.    ListPtr Env;
  332.    {
  333.       Object X;
  334.  
  335.       if (Debug & DebugParse) {
  336.      printf ("InComp: Env = "); 
  337.      OutList (Env); 
  338.      printf (", F = %s\n",F->InPtr);
  339.       }
  340.       X.Tag = BOTTOM;
  341.       if (!InSimple (F,&X,Env)) return 0;
  342.       else {
  343.      InBlanks (F);
  344.      if (!IsTok (F,"|")) {
  345.         RepObject (InOut,&X);
  346.         RepTag (&X,BOTTOM);
  347.         return !SysError;
  348.      } else {
  349.         ListPtr P,R=NIL; 
  350.         boolean Correct;
  351.         NewList (&R,1L);
  352.         if (SysError) Correct = 0;
  353.         else {
  354.            CopyObject (&(P=R)->Val,&X);
  355.            RepTag (&X,BOTTOM);
  356.            do {
  357.           NewList (&P->Next,1L);
  358.           Correct = !SysError && InSimple (F,&(P=P->Next)->Val,NIL);
  359.           InBlanks (F);
  360.            } while (Correct && IsTok (F,"|"));
  361.         }
  362.         return MakeForm (Correct,FormTable[NODE_Comp].FormNode,R,InOut);
  363.      }
  364.       }
  365.    }
  366.  
  367. /*
  368.  * InDef
  369.  *
  370.  * Input a function definition
  371.  *
  372.  * Input
  373.  *      FunName = Name of function
  374.  * Output
  375.  *      InOut = function definition
  376.  *      result = 1 iff successful, 0 otherwise
  377.  */
  378. boolean InDef (F,FunName,InOut)
  379.    register InDesc *F;
  380.    StrPtr FunName;
  381.    ObjectPtr InOut;
  382.    {
  383.       Object Fun,S;
  384.  
  385.       Fun.Tag = BOTTOM;
  386.       S.Tag = BOTTOM;
  387.       F->InDefFun = FunName;
  388.  
  389.       InBlanks (F);
  390.       if (!IsTok (F,"DEF")) return InError (F,"DEF expected");
  391.       else {
  392.      InBlanks (F);
  393.      (void) InString (F,&S,NodeDelim,0);
  394.      if (StrComp (S.String,FunName))
  395.         (void) InError (F,"Definition name wrong");
  396.      else {
  397.         InBlanks (F);
  398.         if (!IsTok (F,"AS")) (void) InError (F,"AS expected");
  399.         else {
  400.            InBlanks (F);
  401.            if (InComp (F,&Fun,NIL)) {
  402.           InBlanks (F);
  403.           if (!IsTok (F,";")) (void) InError (F,"semicolon expected");
  404.           else {
  405.              InBlanks (F);
  406.              if (*F->InPtr) (void) InError (F,"end of file expected");
  407.              else {
  408.             RepTag (&S,BOTTOM);
  409.             CopyObject (InOut,&Fun);
  410.             RepTag (&Fun,BOTTOM);
  411.             return 1;
  412.              }
  413.           }
  414.            }
  415.         }
  416.      }
  417.       }
  418.       RepTag (&S,BOTTOM);
  419.       RepTag (&Fun,BOTTOM);
  420.       return 0;
  421.    }
  422.  
  423.  
  424. /********************************** infun.c **********************************/
  425.  
  426. SHAR_EOF
  427. if test -f 'interp/inimport.c'
  428. then
  429.     echo shar: over-writing existing file "'interp/inimport.c'"
  430. fi
  431. cat << \SHAR_EOF > 'interp/inimport.c'
  432.  
  433. /****** inimport.c ****************************************************/
  434. /**                                                                  **/
  435. /**                    University of Illinois                        **/
  436. /**                                                                  **/
  437. /**                Department of Computer Science                    **/
  438. /**                                                                  **/
  439. /**   Tool: IFP                         Version: 0.5                 **/
  440. /**                                                                  **/
  441. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  442. /**                                                                  **/
  443. /**   Revised by: Arch D. Robison       Date:  Oct 28, 1985          **/
  444. /**                                                                  **/
  445. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  446. /**                            Prof. W. J. Kubitz                    **/
  447. /**                                                                  **/
  448. /**                                                                  **/
  449. /**------------------------------------------------------------------**/
  450. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  451. /**                       All Rights Reserved.                       **/
  452. /**********************************************************************/
  453.  
  454.  
  455. #include <stdio.h>
  456. #include <ctype.h>
  457. #include "struct.h"
  458. #include "node.h"
  459. #include "string.h"
  460. #include "inob.h"
  461.  
  462. /*
  463.  * DoubleDot
  464.  *
  465.  * Append a ".." to path list by deleting last element.
  466.  *       
  467.  * Input
  468.  *      *F = file descriptor
  469.  *      *C = pointer to path list 
  470.  *
  471.  * Output
  472.  *      result = pointer to last null field, null if error.
  473.  */
  474. MetaPtr DoubleDot (F,C)           
  475.    InDesc *F;
  476.    register MetaPtr C;
  477.    {
  478.       register MetaPtr A;
  479.  
  480.       if (*C == NULL) {
  481.      (void) InError (F,"Too many ..'s.");
  482.      return NULL;
  483.       } else {        /* Remove last element from path list R */
  484.      do {
  485.         A = C;
  486.         C = &(*A)->Next;
  487.      } while (*C != NULL);
  488.      DelLPtr (*A);
  489.      *A = NULL;
  490.      return A;
  491.       }
  492.    }
  493.  
  494. /*
  495.  * NodeDelim is the set of pathname delimiters.  Note that '>' and '<' are not
  496.  * in the set since they are (perversely) legal function names.  
  497.  */
  498. char NodeDelim[] = " ,[](){}|;:/\t\n";
  499.  
  500. /*
  501.  * InNode
  502.  *
  503.  * Input a path.  A path may represent a module, function, or functional
  504.  * variable.  Local functions are linked if possible to save time and space.
  505.  *
  506.  * The EBNF production definition for a node is:
  507.  *
  508.  *    ["/"] string { "/" (string | "..") }
  509.  *
  510.  * Input
  511.  *    *F = input descriptor pointing to path
  512.  *    Env = environment
  513.  *
  514.  * Output
  515.  *      InOut = node (path list or node format) or functional variable (string)
  516.  *    *F = input descriptor pointing to next token after path
  517.  *
  518.  * A SysError may occur, in which case InOut is unchanged.
  519.  */
  520. boolean InNode (F,InOut,Env)
  521.    InDesc *F;
  522.    ObjectPtr InOut;
  523.    ListPtr Env;
  524.    {
  525.       ListPtr R = NULL;        /* path list accumulator                       */
  526.       register MetaPtr A = &R; /* pointer to Next field at end of accumulator */
  527.       register NodePtr N;
  528.       boolean FirstSlash;
  529.    
  530.       if (Debug & DebugParse) printf ("InNode: '%s'",F->InPtr); 
  531.       if (!(FirstSlash = *F->InPtr == '/')) {
  532.  
  533.      if (IsTok (F,"..")) {
  534.         if (F->InDefMod != NULL) R = MakePath (F->InDefMod);
  535.         if (NULL == (A = DoubleDot (F,&R))) goto Error;
  536.      } else {
  537.  
  538.         Object S;                       /* relative path */
  539.         S.Tag = BOTTOM;
  540.         if (NULL == InString (F,&S,NodeDelim,0)) {
  541.            if (!SysError) (void) InError (F,"path expected");
  542.            goto Error;
  543.         }    
  544.         if (!IsTok (F,"/")) {
  545.  
  546.            for (; Env!=NULL; Env=Env->Next) 
  547.           if (ObEqual (&Env->Val,&S)) {
  548.              RepObject (InOut,&Env->Val);     /* functional variable */
  549.              return 1;
  550.           }
  551.  
  552.            N = FindNode (F->InDefMod,S.String);   /* local function */
  553.            if (N != NULL) {
  554.           if (N->NodeType == IMPORT) {
  555.  
  556.              /* Imported function - resolve alias */
  557.              RepObject (InOut,&N->NodeData.NodeImp.ImpDef);
  558.  
  559.           } else { /* Local function already linked */
  560.      
  561.              RepTag (InOut,NODE);
  562.              InOut->Node = CopyNPtr (N);
  563.           }
  564.           RepTag (&S,BOTTOM);
  565.           return 1;
  566.            }
  567.         }
  568.         if (F->InDefMod != NULL) R = MakePath (F->InDefMod);
  569.         while (*A != NULL) A = &(*A)->Next;
  570.         NewList (A,1L);
  571.         (*A)->Val.Tag = STRING;
  572.         (*A)->Val.String = S.String;
  573.      }
  574.       }
  575.  
  576.       while (IsTok (F,"/")) {
  577.      if (IsTok (F,".."))
  578.         if (NULL == (A = DoubleDot (F,&R))) return 0;
  579.         else continue;
  580.      else {
  581.         NewList (A,1L);
  582.         if (SysError) goto Error;
  583.         if (NULL == InString (F,&(*A)->Val,NodeDelim,0)) {
  584.            if (SysError) goto Error;
  585.            else if (*F->InPtr != '/' && FirstSlash) {
  586.           (void) DoubleDot (F,&R);
  587.           break;
  588.            } else {
  589.           (void) InError (F,"Invalid path name");
  590.           goto Error;
  591.            }
  592.         }
  593.         A = &(*A)->Next;
  594.      }
  595.      FirstSlash = 0;
  596.       }
  597.  
  598.       RepTag (InOut,LIST);
  599.       InOut->List = R;
  600.       return 1;
  601.  
  602. Error:
  603.       DelLPtr (R);
  604.       return 0;
  605.    }
  606.  
  607. /*
  608.  * InImport
  609.  *
  610.  * Input from an import file.
  611.  *
  612.  * An import file has the following format:
  613.  *
  614.  *      { 'FROM' path 'IMPORT' string {,string} ';' }
  615.  *
  616.  * Input
  617.  *      F = input
  618.  *      M = pointer to module node
  619.  */
  620. void InImport (F,M)
  621.    register InDesc *F;
  622.    register NodePtr M;
  623.    {
  624.       Object Path,Def;
  625.       register NodePtr N;
  626.       MetaPtr A;
  627.  
  628.       F->InDefFun = NULL;
  629.       Path.Tag = BOTTOM;
  630.       Def.Tag = BOTTOM;
  631.  
  632.       while (*F->InPtr) {
  633.  
  634.      if (!IsTok (F,"FROM")) {
  635.         (void) InError (F,"FROM expected");
  636.         break;
  637.      }
  638.  
  639.      (void) InNode (F,&Path,NIL); 
  640.      if (!IsTok (F,"IMPORT")) {
  641.         (void) InError (F,"IMPORT expected");
  642.         break;
  643.      }
  644.  
  645.      while (1) {
  646.  
  647.         if (NULL == InString (F,&Def," ,;\n",0)) {
  648.            if (!SysError) (void) InError (F,"function name expected");
  649.            goto Return;
  650.         }
  651.  
  652.         N = MakeChild (M,Def.String);
  653.  
  654.         switch (N->NodeType) {
  655.  
  656.            case IMPORT:
  657.           (void) InError (F,"duplicate imported identifier");
  658.           break;
  659.  
  660.            case DEF:
  661.           if (N->NRef > 1) {
  662.              (void) InError (F,"identifies function elsewhere");
  663.              break;
  664.           } /* else continue on down to NEWNODE */
  665.  
  666.            case NEWNODE: {
  667.           extern MetaPtr MakeCopy ();
  668.           N->NodeType = IMPORT;
  669.           N->NodeData.NodeImp.ImpDef.Tag = LIST;
  670.           A = MakeCopy (&N->NodeData.NodeImp.ImpDef.List, Path.List);
  671.           NewList (A,1L);
  672.           RepObject (&(*A)->Val,&Def);
  673.           break;
  674.            }
  675.         }
  676.         
  677.         if (IsTok (F,";")) break;
  678.         if (!IsTok (F,",")) {
  679.            (void) InError (F,"comma or semicolon expected");
  680.            goto Return;
  681.         }
  682.      }
  683.       }
  684. Return:
  685.       RepTag (&Path,BOTTOM);
  686.       RepTag (&Def,BOTTOM);
  687.       return;
  688.    }
  689.  
  690.  
  691. /******************************* inimport.c *******************************/
  692.  
  693. SHAR_EOF
  694. if test -f 'interp/inob.c'
  695. then
  696.     echo shar: over-writing existing file "'interp/inob.c'"
  697. fi
  698. cat << \SHAR_EOF > 'interp/inob.c'
  699.  
  700. /****** inob.c ********************************************************/
  701. /**                                                                  **/
  702. /**                    University of Illinois                        **/
  703. /**                                                                  **/
  704. /**                Department of Computer Science                    **/
  705. /**                                                                  **/
  706. /**   Tool: IFP                         Version: 0.5                 **/
  707. /**                                                                  **/
  708. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  709. /**                                                                  **/
  710. /**   Revised by: Arch D. Robison       Date:   Aug 6, 1986          **/
  711. /**                                                                  **/
  712. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  713. /**                            Prof. W. J. Kubitz                    **/
  714. /**                                                                  **/
  715. /**                                                                  **/
  716. /**------------------------------------------------------------------**/
  717. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  718. /**                       All Rights Reserved.                       **/
  719. /**********************************************************************/
  720.  
  721. /*************** object input parser (recursive descent) ***************/
  722.  
  723.  
  724. #include <stdio.h>
  725. #include <ctype.h>
  726. #include "struct.h"
  727. #include "node.h"
  728. #include "string.h"
  729. #include "inob.h"
  730.  
  731. /*
  732.  * ObDelim
  733.  *
  734.  * Theses characters delimit objects.
  735.  * Compare with NodeDelim in inimport.c 
  736.  */
  737. private char ObDelim[] = " ,<>|[](){};:\t\n";
  738.  
  739. /*
  740.  * InBlanks
  741.  *
  742.  * Skip to first non-blank character not in comment.
  743.  *
  744.  * Input
  745.  *     F = input descriptor
  746.  *
  747.  * Output
  748.  *    F = input descriptor pointing to non-blank character
  749.  */
  750. void InBlanks (F)
  751.    register InDesc *F;
  752.    {
  753.       while (1) {
  754.  
  755.      while (1) {
  756.         if (!*F->InPtr)
  757.            if (F->InLineNum >= 0) 
  758.           if (NULL != fgets (F->InBuf,INBUFSIZE,F->InFile)) {
  759.              F->InPtr = F->InBuf;
  760.              F->InLineNum++;
  761.           }
  762.         if (!isspace (*F->InPtr)) break;
  763.         F->InPtr++;
  764.      }
  765.  
  766.      if (*F->InPtr == '(' && F->InPtr[1] == '*') {
  767.         F->ComLevel++;
  768.         F->InPtr+=2;
  769.      } else if (*F->InPtr == '*' && F->InPtr[1] == ')') {
  770.         F->ComLevel--;
  771.         F->InPtr+=2;
  772.      } else if (F->ComLevel && *F->InPtr) F->InPtr++;
  773.      else break;
  774.       }
  775.    }
  776.  
  777. /*
  778.  * IsTok
  779.  *
  780.  * Check if next token in input is S.  Skip if found.
  781.  */
  782. boolean IsTok (F,S)
  783.    InDesc *F;
  784.    register char *S;
  785.    {
  786.       register char *T;
  787.  
  788.       for (T = F->InPtr; *S; S++,T++)
  789.      if (*S != *T) return 0;
  790.  
  791.       /* Check if alphabetic token is prefix of longer token */
  792.       if (isalpha (T[-1]) && isalpha (T[0])) return 0; 
  793.  
  794.       F->InPtr = T;
  795.       InBlanks (F);
  796.       return 1;
  797.    }
  798.  
  799. /*
  800.  * InString
  801.  *
  802.  * Input a string. 
  803.  *
  804.  * Input
  805.  *      *F = input descriptor pointing to first character of string
  806.  *      Delim = string of non-alphanumeric delimiters
  807.  *      Quoted = skip closing delimiter
  808.  *
  809.  * Output
  810.  *      *F = input descriptor pointing to next token after string
  811.  *      X = string object
  812.  *      result = pointer to string, NULL if SysError or empty string.
  813.  *
  814.  * A SysError may occur, in which case X = bottom.
  815.  */
  816. StrPtr InString (F,X,Delim,Quoted)
  817.    register InDesc *F;
  818.    ObjectPtr X;
  819.    char *Delim;
  820.    boolean Quoted;
  821.    {
  822.       CharPtr U;
  823.       register char C;
  824.  
  825.       RepTag (X,STRING);
  826.       X->String = NULL;
  827.       CPInit (&U,&X->String);
  828.       do {
  829.          extern char *index ();
  830.      C = *F->InPtr++;
  831.      if (!isalnum (C) && NULL != index (Delim,C)) C = '\0';
  832.      CPAppend (&U,C);
  833.      if (SysError) {RepTag (X,BOTTOM); return NULL;}
  834.       } while (C);
  835.       if (!Quoted) F->InPtr--;
  836.       InBlanks (F);
  837.       return X->String;
  838.    }
  839.  
  840.  
  841. /*
  842.  * InList
  843.  *
  844.  * Input a list
  845.  *
  846.  * Input
  847.  *     F = input descriptor pointing to first token after '<'
  848.  *
  849.  * Output
  850.  *     result = true iff no error occurs
  851.  *     *X = sequence, or unchanged if error occurs.
  852.  */
  853. private boolean InList (F,X)
  854.    register InDesc *F;
  855.    ObjectPtr X;
  856.    {
  857.       ListPtr R=NULL;
  858.       register MetaPtr A = &R;
  859.  
  860.       while (!IsTok (F,">")) {
  861.      if (!*F->InPtr) {
  862.         DelLPtr (R);
  863.         return InError (F,"unfinished sequence");
  864.      }   
  865.      NewList (A,1L);
  866.      if (SysError || !InObject (F,&(*A)->Val)) {
  867.         DelLPtr (R);
  868.         return 0;
  869.      }
  870.      A = & (*A)->Next;
  871.      (void) IsTok (F,",");
  872.       }
  873.       RepTag (X,LIST);
  874.       X->List = R;
  875.       return 1;
  876.    }
  877.  
  878. /*
  879.  * InObject
  880.  *
  881.  * Read an object.
  882.  *
  883.  * Input
  884.  *      *F = input descriptor pointing to object
  885.  *
  886.  * Output
  887.  *      *F = input descriptor pointing to next token
  888.  *    result = true iff object is read successfully.
  889.  *
  890.  * A SysError may occur, in which case X is unchanged.
  891.  */
  892. boolean InObject (F,X)
  893.    register InDesc *F;
  894.    register ObjectPtr X;
  895.    {
  896.       if (IsTok (F,"<")) return InList (F,X);
  897.  
  898.       else if (IsTok (F,"(")) {
  899.  
  900.      (void) InComp (F,X,NIL);
  901.      if (!IsTok (F,")")) return InError (F,"')' expected");
  902.  
  903.       } else { 
  904.  
  905.      /* Input atom */
  906.  
  907.      static char Delim[2] = {'\0','\0'};
  908.      *Delim = *F->InPtr;
  909.  
  910.      if (*Delim == '\"' || *Delim == '\'') {
  911.         F->InPtr++;
  912.         (void) InString (F,X,Delim,1);
  913.      } else {
  914.  
  915.         FPint K;
  916.         register StrPtr S = InString (F,X,ObDelim,0);
  917.         if (S == NULL) return SysError || InError (F,"object expected");
  918.         if (S->StrChar[1] == '\0')
  919.            switch (S->StrChar[0]) {
  920.           case 'f':
  921.              RepBool (X,0);
  922.              return 1;
  923.           case 't':
  924.              RepBool (X,1);
  925.              return 1;
  926.           case '?':
  927.              RepTag (X,BOTTOM);
  928.              return 1;
  929.            }
  930.         if (StrToFloat (X) && !GetFPInt (X,&K)) {
  931.            X->Tag = INT;
  932.            X->Int = K;
  933.         } 
  934.      }
  935.       }
  936.       return 1;
  937.    }
  938.  
  939. /*
  940.  * InitIn
  941.  *
  942.  * Initialize input descriptor for node N and file FileDesc.
  943.  * Advance the input pointer to the first token.
  944.  *
  945.  * Input
  946.  *    *F = input descriptor
  947.  *    M = module pointer
  948.  *    FileDesc = open file descriptor
  949.  *    LineNum = 0 for normal input, -1 if single-line mode
  950.  */
  951. void InitIn (F,M,FileDesc,LineNum)
  952.    register InDesc *F;
  953.    NodePtr M;
  954.    FILE *FileDesc;
  955.    int LineNum;
  956.    {
  957.       F->InFile = FileDesc;
  958.       F->InLineNum= LineNum;
  959.       F->InPtr = F->InBuf;
  960.       *F->InPtr = '\0';
  961.       F->InDefMod = M;
  962.       F->ComLevel = 0;
  963.       InBlanks (F);
  964.    }
  965.  
  966.  
  967. /******************************* end of inob.c *******************************/
  968.  
  969. SHAR_EOF
  970. if test -f 'interp/inob.h'
  971. then
  972.     echo shar: over-writing existing file "'interp/inob.h'"
  973. fi
  974. cat << \SHAR_EOF > 'interp/inob.h'
  975.  
  976. /****** inob.h ********************************************************/
  977. /**                                                                  **/
  978. /**                    University of Illinois                        **/
  979. /**                                                                  **/
  980. /**                Department of Computer Science                    **/
  981. /**                                                                  **/
  982. /**   Tool: IFP                         Version: 0.5                 **/
  983. /**                                                                  **/
  984. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  985. /**                                                                  **/
  986. /**   Revised by: Arch D. Robison       Date:  Sept 9, 1986          **/
  987. /**                                                                  **/
  988. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  989. /**                            Prof. W. J. Kubitz                    **/
  990. /**                                                                  **/
  991. /**                                                                  **/
  992. /**------------------------------------------------------------------**/
  993. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  994. /**                       All Rights Reserved.                       **/
  995. /**********************************************************************/
  996.  
  997. #define INBUFSIZE 255     /* 65 <= INBUFSIZE <= 255 for DOS */
  998.  
  999. /*
  1000.  * InDesc
  1001.  *
  1002.  * Input descriptor.
  1003.  *
  1004.  * Currently, there are three forms of IFP input:
  1005.  *
  1006.  *    1. Definition files
  1007.  *    2. Import files
  1008.  *    3. Terminal input
  1009.  *
  1010.  * All three forms are managed by input descriptors.  An input descriptor
  1011.  * buffers the file, and keeps track of context (e.g. line number).
  1012.  */
  1013.  
  1014. typedef struct {
  1015.    char *InPtr;           /* Pointer to current character being scanned   */
  1016.    int InLineNum;         /* Line number of line being read [1]           */
  1017.    int ComLevel;      /* Current comment nesting level [2]          */
  1018.    NodePtr InDefMod;      /* Module node of current definition being read */
  1019.    StrPtr InDefFun;       /* Name of current definition                   */
  1020.    FILE *InFile;          /* File descriptor of file being read           */
  1021.    char InBuf[INBUFSIZE]; /* Buffer for current line being scanned        */
  1022. } InDesc;
  1023.  
  1024. /*
  1025.  * Footnotes
  1026.  *
  1027.  * [1] A line number of -1 indicates unnumbered lines, i.e. terminal input. 
  1028.  *
  1029.  * [2] ComLevel should always be zero outside of function "InBlanks".
  1030.  *     A non-zero value indicates an "open comment" error.
  1031.  */
  1032.  
  1033. extern StrPtr InString ();
  1034. extern char NodeDelim[];
  1035.  
  1036. /******************************* end of inob.h *******************************/
  1037.  
  1038. SHAR_EOF
  1039. if test -f 'interp/list.c'
  1040. then
  1041.     echo shar: over-writing existing file "'interp/list.c'"
  1042. fi
  1043. cat << \SHAR_EOF > 'interp/list.c'
  1044.  
  1045. /****** list.c ********************************************************/
  1046. /**                                                                  **/
  1047. /**                    University of Illinois                        **/
  1048. /**                                                                  **/
  1049. /**                Department of Computer Science                    **/
  1050. /**                                                                  **/
  1051. /**   Tool: IFP                         Version: 0.5                 **/
  1052. /**                                                                  **/
  1053. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  1054. /**                                                                  **/
  1055. /**   Revised by: Arch D. Robison       Date:  Jan 15, 1986          **/
  1056. /**                                                                  **/
  1057. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  1058. /**                            Prof. W. J. Kubitz                    **/
  1059. /**                                                                  **/
  1060. /**                                                                  **/
  1061. /**------------------------------------------------------------------**/
  1062. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  1063. /**                       All Rights Reserved.                       **/
  1064. /**********************************************************************/
  1065.  
  1066. #include <stdio.h>
  1067. #include "struct.h"
  1068. #include "node.h"
  1069. #include "umax.h"
  1070. #include "string.h"
  1071. #include "stats.h"
  1072.  
  1073. /* 
  1074.  * FreeList
  1075.  *
  1076.  * ListCells in free-list always contain:
  1077.  *
  1078.  *      LRef == LRefOne 
  1079.  *      Val.Tag == BOTTOM
  1080.  *      Next == pointer to next cell in free list.
  1081.  */
  1082. ListPtr FreeList = NULL;
  1083. #define LRefAdd(P,Delta) ((P)->LRef+=(Delta))
  1084.  
  1085. /*************** Fundamental List Manipulation Routines ***************/
  1086.  
  1087. private ListPtr FixCopyLPtr ();         /* forward reference */
  1088.  
  1089. /*
  1090.  * Rot3
  1091.  */
  1092. void Rot3 (A,B,C)
  1093.    MetaPtr A,B,C;
  1094.    {
  1095.       register ListPtr P;
  1096.       P = *A; *A = *B; *B = *C; *C = P;
  1097.    }
  1098.  
  1099. /*
  1100.  * ListLength
  1101.  *
  1102.  * Input
  1103.  *      P = pointer to list
  1104.  *
  1105.  * Output
  1106.  *      result = length of list
  1107.  */
  1108. long ListLength (P)
  1109.    register ListPtr P;
  1110.    {
  1111.       register long N;
  1112.       for (N=0; P!=NULL; P=P->Next) N++;
  1113.       return N;
  1114.    }
  1115.  
  1116. /*
  1117.  * CopyObject
  1118.  *
  1119.  * Copy object: X := Y
  1120.  *
  1121.  * A SysError may occur.
  1122.  */
  1123. void CopyObject (X,Y)
  1124.    ObjectPtr X,Y;
  1125.    {
  1126.       register ListPtr P;
  1127.  
  1128.       switch (X->Tag = Y->Tag) {
  1129.      case BOTTOM: break;
  1130.      case BOOLEAN: X->Bool   = Y->Bool;              break;
  1131.      case INT:     X->Int    = Y->Int;               break;
  1132.      case FLOAT:   X->Float  = Y->Float;             break;
  1133.      case LIST:
  1134.          /* CopyLPtr expanded inline for speed */
  1135.          P = Y->List;
  1136.          if (P!=NULL && LRefAdd (P,1) == LRefOne-1) 
  1137.         /*
  1138.          * This won't work for multiprocessor version
  1139.          * since other processors will not detect overflow.
  1140.          */
  1141.         P = FixCopyLPtr (P);
  1142.          X->List = P;
  1143.          break;
  1144.      case STRING:  X->String = CopySPtr (Y->String);        break;
  1145.      case NODE:    X->Node   = CopyNPtr (Y->Node);      break;
  1146.       }
  1147.    }
  1148.  
  1149. /*
  1150.  * NewList
  1151.  *
  1152.  * Point *A to list of N cells with last cell's Next set to old value of *A.
  1153.  *
  1154.  * Each cell value is set to BOTTOM
  1155.  *
  1156.  * A SysError may occur, in which case *A remains unchanged.
  1157.  *
  1158.  * Implementation note: 
  1159.  *     (x >= 0) is faster than (x > 0) on 16-bit machines since only
  1160.  *     the sign bit must be checked.
  1161.  */
  1162. void NewList (A,N)
  1163.    MetaPtr A;
  1164.    register long N;
  1165.    {
  1166.       extern ListPtr AllocListPage ();
  1167.       register MetaPtr B;
  1168.       ListPtr P;
  1169.  
  1170.       Stat (StatNewList (N));
  1171.       if (--N >= 0) {
  1172.      B = &FreeList;
  1173.      do {
  1174.         if (*B == NULL && (*B = AllocListPage ()) == NULL) {
  1175.            SysError = NO_LIST_FREE;
  1176.            printf ("NO MORE LIST CELLS LEFT\n");
  1177.            return;
  1178.         }
  1179.         B = &(*B)->Next;
  1180.      } while (--N >= 0);
  1181.      P = FreeList;
  1182.      FreeList = *B;
  1183.      *B = *A;
  1184.      *A = P;
  1185.       }
  1186.    }
  1187.  
  1188. /*
  1189.  * Repeat
  1190.  *
  1191.  * Create a new list containing N copies of an object
  1192.  *
  1193.  * Output
  1194.  *      result = pointer to list
  1195.  *
  1196.  * A SysError may occur, in which case NULL is returned.
  1197.  */
  1198. ListPtr Repeat (X,N)
  1199.    register ObjectPtr X; 
  1200.    long N;
  1201.    {
  1202.       ListPtr P=NULL;
  1203.       register ListPtr Q;
  1204.  
  1205.       NewList (&P,N);
  1206.       if (!SysError)
  1207.      for (Q=P; Q!=NULL; Q=Q->Next) 
  1208.         CopyObject (&Q->Val,X); 
  1209.       return P;
  1210.    }
  1211.  
  1212. /*
  1213.  * DelLPtr
  1214.  *
  1215.  * Delete a list pointer: decrement reference count and return to free-list
  1216.  *                        if not used anymore.
  1217.  *
  1218.  * Routine is "vectorized" in that it is optimized to return long lists
  1219.  * to the freelist.
  1220.  */
  1221. void DelLPtr (P)
  1222.    register ListPtr P;
  1223.    {
  1224.       register ListPtr Q,R;
  1225.  
  1226.       Stat (StatDelLPtr (P));
  1227.  
  1228.       for (R=P; R!=NULL; R=R->Next) {
  1229.          if (R->LRef != LRefOne) {
  1230.         R->LRef--;
  1231.         break;
  1232.      }
  1233.      if (!Scalar (R->Val.Tag)) {
  1234.         switch (R->Val.Tag) {
  1235.            case LIST:     DelLPtr (R->Val.List);     break;
  1236.            case STRING:   DelSPtr (R->Val.String);   break;
  1237.            case NODE:     DelNPtr (R->Val.Node);     break;
  1238.         }
  1239.         R->Val.Tag = BOTTOM;
  1240.      }
  1241.      Q = R;
  1242.       }
  1243.       if (R != P) {
  1244.      Q->Next = FreeList; 
  1245.      FreeList = P;
  1246.       }
  1247.    }
  1248.  
  1249. /*
  1250.  * CopyLPtr
  1251.  *
  1252.  * Make a copy of a list pointer, incrementing the reference count.
  1253.  * If the reference count would overflow, a new list cell is generated.
  1254.  *
  1255.  * A SysError may occur, in which case the result is NULL.
  1256.  */
  1257. ListPtr CopyLPtr (P)
  1258.    ListPtr P;
  1259.    {
  1260.       if (P!=NULL) {
  1261.          if (LRefAdd (P,1) == LRefOne-1) {
  1262.             return FixCopyLPtr (P);
  1263.          }
  1264.       }
  1265.       return P;
  1266.    }
  1267.  
  1268. /*
  1269.  * FixCopyLPtr 
  1270.  * 
  1271.  * Copy a list pointer which overflowed.
  1272.  *
  1273.  * Input
  1274.  *    P = pointer to list cell
  1275.  */
  1276. private ListPtr FixCopyLPtr (P)
  1277.    ListPtr P;
  1278.    {
  1279.       ListPtr Q;                        /* Reference count overflowed */
  1280.  
  1281.       LRefAdd (P,-1);
  1282.       Q = CopyLPtr (P->Next);
  1283.       if (SysError) return NULL;
  1284.       NewList (&Q,1L);
  1285.       if (SysError) return NULL;
  1286.       CopyObject (&Q->Val,&P->Val);
  1287.       return Q;
  1288.    }
  1289.  
  1290. /*
  1291.  * RepTag
  1292.  *
  1293.  * Replace an object tag with another tag.
  1294.  */
  1295. void RepTag (Dest,NewTag)
  1296.    ObjectPtr Dest;
  1297.    char NewTag;
  1298.    {
  1299.       switch (Dest->Tag) {
  1300.      case LIST:     DelLPtr (Dest->List);     break;
  1301.      case STRING:   DelSPtr (Dest->String);   break;
  1302.      case NODE:     DelNPtr (Dest->Node);     break;
  1303.      /* default: break; */
  1304.       }
  1305.       Dest->Tag = NewTag;
  1306.    }
  1307.  
  1308. /*
  1309.  * RepBool
  1310.  *
  1311.  * Replace an object with a boolean object
  1312.  */
  1313. void RepBool (Dest,Value)
  1314.    ObjectPtr Dest;
  1315.    boolean Value;
  1316.    {
  1317.       RepTag (Dest,BOOLEAN);
  1318.       Dest->Bool = Value;
  1319.    }
  1320.  
  1321. /*
  1322.  * RepObject
  1323.  *
  1324.  * Replace an Object by another Object.
  1325.  *
  1326.  * A SysError may occur.
  1327.  */
  1328. boolean RepObject (Y,X)
  1329.    register ObjectPtr Y,X;
  1330.    {
  1331.       Object Z;
  1332.  
  1333.       switch (Z.Tag = Y->Tag) {
  1334.      case LIST:   Z.List   = Y->List;   break;
  1335.      case STRING: Z.String = Y->String; break;
  1336.      case NODE:   Z.Node   = Y->Node;   break;
  1337.       }
  1338.       switch (Y->Tag = X->Tag) {
  1339.      case BOTTOM:    break;
  1340.      case BOOLEAN:   Y->Bool   = X->Bool;              break;
  1341.      case INT:       Y->Int    = X->Int;               break;
  1342.      case FLOAT:     Y->Float  = X->Float;             break;
  1343.      case LIST:      Y->List   = CopyLPtr (X->List);   break;
  1344.      case STRING:    Y->String = CopySPtr (X->String); break;
  1345.      case NODE:      Y->Node   = CopyNPtr (X->Node);   break;
  1346.       }
  1347.       switch (Z.Tag) {
  1348.      case LIST:   DelLPtr (Z.List);   break;
  1349.      case STRING: DelSPtr (Z.String); break;
  1350.      case NODE:   DelNPtr (Z.Node);   break;
  1351.       }
  1352.    }
  1353.  
  1354.  
  1355. /*
  1356.  * RepLPtr
  1357.  *
  1358.  * Replace pointer variable *A by value B.
  1359.  *
  1360.  * A SysError may occur, in which case *A remains unchanged.
  1361.  */
  1362. void RepLPtr (A,P)
  1363.    MetaPtr A; 
  1364.    ListPtr P;
  1365.    {
  1366.       P = CopyLPtr (P); /* Copy P first so DelLPtr can't trash *P */
  1367.       if (SysError) return;
  1368.       DelLPtr (*A);
  1369.       *A = P;
  1370.    }
  1371.  
  1372.  
  1373. /*
  1374.  * MakeCopy
  1375.  *
  1376.  * Make a copy of a non-empty list.
  1377.  *
  1378.  * Input
  1379.  *      P = pointer to list
  1380.  *
  1381.  * Output
  1382.  *      *A = pointer to identical list with LRef == LRefOne
  1383.  *      result = metapointer to Next field of end of result list
  1384.  *
  1385.  * A SysError may occur, in which case *A remains unchanged.
  1386.  *
  1387.  * All sublist-head reference-counts are incremented if no error occurs.
  1388.  */
  1389. MetaPtr MakeCopy (A,P)
  1390.    register ListPtr *A,P;
  1391.    {
  1392.       register ListPtr Q;
  1393.       ListPtr R=NULL;         /* R = root of new list */
  1394.  
  1395.       NewList (&R,ListLength (P));
  1396.       if (SysError) return NULL;
  1397.  
  1398.       Q = R;
  1399.       while (1) {
  1400.      if (Scalar (P->Val.Tag)) {
  1401.         Q->Val.Data = P->Val.Data;
  1402.         Q->Val.Tag  = P->Val.Tag;
  1403.      } else {
  1404.         CopyObject (& Q->Val,& P->Val);
  1405.         if (SysError) {DelLPtr (R); return NULL;};
  1406.      }
  1407.      P = P->Next;
  1408.      if (P == NULL) break;
  1409.      Q = Q->Next;
  1410.       };
  1411.  
  1412.       *A = R;
  1413.       return &Q->Next;
  1414.    }
  1415.  
  1416.  
  1417. /*
  1418.  * CopyTop
  1419.  *
  1420.  * Replace *A with a pointer to a fresh (top level) copy of *A.
  1421.  *
  1422.  * Input
  1423.  *      *A = pointer to list
  1424.  * Output
  1425.  *      *A = pointer to identical list with LRef == LRefOne for top level
  1426.  *
  1427.  * A SysError may occur, in which case *A remains unchanged.
  1428.  */
  1429. void CopyTop (A)
  1430.    register MetaPtr A;
  1431.    {
  1432.       register ListPtr P;
  1433.  
  1434.       while (1) {                 /* Search for shared part of list */
  1435.      P = *A;
  1436.      if (P == NULL) return;
  1437.      if (P->LRef != LRefOne) break;
  1438.      Stat (StatRecycle++);
  1439.      A = & P->Next;
  1440.       }
  1441.  
  1442.       (void) MakeCopy (A,P);
  1443.       P->LRef--;
  1444.       if (SysError) (*A)->LRef++;
  1445.    }
  1446.  
  1447.  
  1448. /*
  1449.  * Copy2Top
  1450.  *
  1451.  * Replace *A with a pointer to a fresh (top 2 levels) of *A.
  1452.  *
  1453.  * Input
  1454.  *      *A = pointer to list
  1455.  * Output
  1456.  *      *A = pointer to identical list with LRef == LRefOne
  1457.  *           for both top level and any immediate sublists.
  1458.  *
  1459.  * A SysError may occur, in which case *A remains unchanged.
  1460.  */
  1461. void Copy2Top (A)
  1462.    register MetaPtr A;
  1463.    {
  1464.       register ListPtr P;
  1465.  
  1466.       while (1) {                 /* Search for shared part of list */
  1467.      P = *A;
  1468.      if (P == NULL) return;
  1469.      if (P->LRef != LRefOne) break;
  1470.      if (P->Val.Tag == LIST) {
  1471.         CopyTop (&P->Val.List);
  1472.         if (SysError) return;
  1473.      }
  1474.      Stat (StatRecycle++);
  1475.      A = & P->Next;
  1476.       }
  1477.  
  1478.       /* (*A) now points to shared list */
  1479.  
  1480.       (void) MakeCopy (A,(P = *A));
  1481.  
  1482.       if (SysError) return;
  1483.       P->LRef--;
  1484.       P = *A;
  1485.  
  1486.       do
  1487.      if (P->Val.Tag == LIST && *(A = &P->Val.List) != NULL) {
  1488.         /*
  1489.          * There must some more elegant way to efficiently merge these 
  1490.          * two cases.
  1491.          */
  1492.         (*A)->LRef--; /* will be incremented by MakeCopy */
  1493.             (void) MakeCopy (A,*A);
  1494.         if (SysError) return;
  1495.      }
  1496.       while ((P=P->Next) != NULL);
  1497.    }
  1498.  
  1499.  
  1500. /****************************** end of list.c ******************************/
  1501.  
  1502. SHAR_EOF
  1503. if test -f 'interp/main.c'
  1504. then
  1505.     echo shar: over-writing existing file "'interp/main.c'"
  1506. fi
  1507. cat << \SHAR_EOF > 'interp/main.c'
  1508.  
  1509. /****** main.c ********************************************************/
  1510. /**                                                                  **/
  1511. /**                    University of Illinois                        **/
  1512. /**                                                                  **/
  1513. /**                Department of Computer Science                    **/
  1514. /**                                                                  **/
  1515. /**   Tool: IFP                         Version: 0.5                 **/
  1516. /**                                                                  **/
  1517. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  1518. /**                                                                  **/
  1519. /**   Revised by: Arch D. Robison       Date:  Jan 20, 1987          **/
  1520. /**                                                                  **/
  1521. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  1522. /**                            Prof. W. J. Kubitz                    **/
  1523. /**                                                                  **/
  1524. /**                                                                  **/
  1525. /**------------------------------------------------------------------**/
  1526. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  1527. /**                       All Rights Reserved.                       **/
  1528. /**********************************************************************/
  1529.  
  1530. #include <stdio.h>
  1531. #include "struct.h"
  1532. #include "node.h"
  1533. #include "umax.h"
  1534. #include "cache.h"
  1535. #include "stats.h"
  1536.  
  1537. #if OPSYS!=CTSS
  1538. #endif
  1539.  
  1540. static char Version[] = "\nIllinois FP 0.5";
  1541. static char Author [] = " Arch D. Robison";
  1542. static char Date   [] = " Dec 5, 1986\n";
  1543.  
  1544. #if OPSYS==UNIX
  1545. #define OPSYSTEM "UNIX"
  1546. #endif
  1547. #if OPSYS==MSDOS
  1548. #define OPSYSTEM "MS-DOS"
  1549. #endif
  1550. #if OPSYS==CTSS
  1551. #define OPSYSTEM "CTSS"
  1552. #endif
  1553.  
  1554. boolean LongPathFlag = 0;
  1555.  
  1556. #ifdef COMPILE
  1557. boolean CompilerFlag = 0;       /* Enable compiler if set */
  1558. boolean RuleFlag = 0;           /* Display rules if set   */
  1559. #endif
  1560.  
  1561. private void Init ()
  1562.    {
  1563.       extern void D_arith (), D_form (), D_pred (), D_misc (), D_seq (), 
  1564.           D_ss (), D_subseq (), D_string (), D_cray (), D_vector ();
  1565.       extern void InitString (), InitNode (), InitFile ();
  1566.       extern char RootPath[];                  /* from file.c */
  1567. #if OPSYS==MSDOS
  1568.       char CWD [64];
  1569. #endif
  1570. #if OPSYS==UNIX
  1571.       extern void EnvGet ();
  1572. #endif    
  1573.       if (Debug & DebugInit) printf ("enter Init\n");
  1574.  
  1575.       InitString ();
  1576. #if OPSYS==MSDOS
  1577.       CWDGet (CWD,MAXPATH);
  1578. #endif
  1579. #if OPSYS==UNIX
  1580.       EnvGet ("IFProot",RootPath,MAXPATH);      /* Check for RootPath */
  1581. #endif 
  1582. #if ECACHE
  1583.       InitCache ();
  1584. #endif
  1585.  
  1586.       InitNode ();
  1587.       D_arith ();
  1588.       D_form ();
  1589.       D_pred ();
  1590.       D_seq ();
  1591.       D_subseq ();
  1592.       D_misc ();
  1593.       D_ss ();
  1594.       D_string ();
  1595. #if OPSYS==MSDOS
  1596.       InitFile (CWD);
  1597. #endif
  1598. #if OPSYS==UNIX || OPSYS==CTSS
  1599.       InitFile ();
  1600. #endif
  1601. #ifdef COMPILE
  1602.       if (CompilerFlag) {
  1603.      extern void InitSymTab (), InitCompiler ();
  1604.      InitSymTab ();
  1605.      InitCompiler ();
  1606.       }
  1607. #endif
  1608. #ifdef GRAPHICS
  1609.       InitDraw (); /* for CS9000 graphics only */
  1610. #endif
  1611. #if STATS
  1612.       printf (" (stats)");
  1613. #endif
  1614.       if (Debug & DebugInit) printf ("exit Init\n");
  1615.    }
  1616.  
  1617. extern void UserLoop ();
  1618.  
  1619. /*
  1620.  * GetOptions
  1621.  *
  1622.  * Process command line options.
  1623.  *
  1624.  * Input
  1625.  *     argv = command line arguments
  1626.  *    argc = argument count
  1627.  */
  1628. private void GetOptions (argc,argv)
  1629.    int argc;
  1630.    char *argv[];
  1631.    {
  1632.       int k;
  1633.       char *P;
  1634.  
  1635.       for (k=1; k<argc; k++) 
  1636.      if (*(P=argv[k]) == '-') 
  1637.         while (*P && *++P)
  1638.            switch (*P) {
  1639. #ifdef COMPILE
  1640.           case 'c': CompilerFlag = 1; break;
  1641.           case 'r': RuleFlag = 1; break;
  1642. #endif 
  1643. #if DEBUG
  1644.           case 'd': 
  1645.              while (*++P) {
  1646.                 extern char *index();
  1647.             static char Opt[] = DebugOpt;
  1648.                 char *t = index (Opt,*P);
  1649.             if (t != NULL) Debug |= 1 << (t-Opt);
  1650.             else printf ("[unknown option = -d%c] ",*P);
  1651.              }
  1652.              break; 
  1653. #endif /* DEBUG */
  1654. #if ECACHE
  1655.           case 'e':
  1656.              while (*++P)
  1657.             if (*P >= '0' && *P <= '2')
  1658.                Cache[*P-'0'].Enable = 1;
  1659.             else
  1660.                printf ("[unknown -e option = %c] ",*P);
  1661.              break;
  1662. #endif /* ECACHE */
  1663.           case 'l': LongPathFlag = 1; break;
  1664.           default: 
  1665.              printf ("[unknown option = %c] ",*P);
  1666.              P = "";
  1667.              break;
  1668.            }
  1669.    }
  1670.  
  1671. main (argc, argv)
  1672.    int argc;
  1673.    char *argv[];
  1674.    {
  1675.       printf ("%s: (%s)",Version,OPSYSTEM);
  1676.       (void) fflush (stdout);
  1677.       GetOptions (argc,argv);
  1678.       Init ();
  1679.       printf ("\n\n");
  1680.       UserLoop ();
  1681.       Terminate();
  1682.       if (Debug & DebugInit) printf ("normal exit\n");
  1683.       exit (0);
  1684.    }
  1685.  
  1686. /************************** end of main.c **************************/
  1687.  
  1688. SHAR_EOF
  1689. if test -f 'interp/node.c'
  1690. then
  1691.     echo shar: over-writing existing file "'interp/node.c'"
  1692. fi
  1693. cat << \SHAR_EOF > 'interp/node.c'
  1694.  
  1695. /****** node.c ********************************************************/
  1696. /**                                                                  **/
  1697. /**                    University of Illinois                        **/
  1698. /**                                                                  **/
  1699. /**                Department of Computer Science                    **/
  1700. /**                                                                  **/
  1701. /**   Tool: IFP                         Version: 0.5                 **/
  1702. /**                                                                  **/
  1703. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  1704. /**                                                                  **/
  1705. /**   Revised by: Arch D. Robison       Date:  Nov 23, 1985          **/
  1706. /**                                                                  **/
  1707. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  1708. /**                            Prof. W. J. Kubitz                    **/
  1709. /**                                                                  **/
  1710. /**                                                                  **/
  1711. /**------------------------------------------------------------------**/
  1712. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  1713. /**                       All Rights Reserved.                       **/
  1714. /**********************************************************************/
  1715.  
  1716. #include <stdio.h>
  1717. #include "struct.h"
  1718. #include "node.h"
  1719. #include "umax.h"
  1720. #include "string.h"
  1721.  
  1722. /********************************* NODE RULES ******************************
  1723.  
  1724. Function definitions are stored in nodes, which are arranged in a tree
  1725. structure mimicking the UNIX file structure.  Below is an example:
  1726.  
  1727.            Rm
  1728.            |
  1729.            Am---Bi----Cm-------Dd
  1730.            |          |
  1731.            Xd         Yd--Zd
  1732.  
  1733. Rm is the root node, with children Am,Bi,Cm, and Dd. Nodes can be one of three
  1734. types: module (m), import (i), or definition (d).  Only definition nodes
  1735. have a reference count greater than 1.  Only module nodes have children.
  1736.  
  1737.  ****************************** end of node rules **************************/
  1738.  
  1739. NodePtr RootNode,SysNode,LogicNode,ArithNode;
  1740.  
  1741. /* Free nodes have NREF == 0 and are linked by NodeSib field */
  1742. NodePtr FreeNode = NULL;
  1743.  
  1744. /*
  1745.  * DelNPtr
  1746.  *
  1747.  * Note: node pointers always have a parent pointer to them, so
  1748.  *       we don't have to delete them here.
  1749.  *
  1750.  * Input
  1751.  *    N = pointer to node
  1752.  */
  1753. void DelNPtr (N)
  1754.    NodePtr N;
  1755.    {
  1756.       rsemaphore_enter (NRefSemaphore);
  1757.       if (N != NULL) N->NRef--;
  1758.       rsemaphore_exit (NRefSemaphore);
  1759.    }
  1760.  
  1761.  
  1762. /*
  1763.  * CopyNPtr
  1764.  */
  1765. NodePtr CopyNPtr (N)
  1766.    NodePtr N;
  1767.    {
  1768.       rsemaphore_enter (NRefSemaphore);
  1769.       if (N != NULL && !++N->NRef) IntError ("CopyNPtr: too many refs");
  1770.       rsemaphore_exit (NRefSemaphore);
  1771.       return N;
  1772.    }
  1773.     
  1774.  
  1775. /*
  1776.  * NewNode
  1777.  *
  1778.  * Point *N to new node from free list.  The input value of *N is
  1779.  * put in the NodeSib field of the new node.
  1780.  *
  1781.  * A SysError may occur, in which case *N is unchanged.
  1782.  */
  1783. private void NewNode (N)
  1784.    NodePtr *N;
  1785.    {
  1786.       extern NodePtr AllocNodePage ();
  1787.       register NodePtr T;
  1788.  
  1789.       rsemaphore_enter (NRefSemaphore);
  1790.       if (FreeNode == NULL && (FreeNode = AllocNodePage ()) == NULL) {
  1791.      printf ("NO MORE NODE CELLS LEFT\n");
  1792.      SysError = NO_NODE_FREE;
  1793.       } else {
  1794.      T = FreeNode;
  1795.      FreeNode = FreeNode->NodeSib;
  1796.      T->NodeSib = *N;
  1797.      *N = T;
  1798.       }
  1799.       rsemaphore_exit (NRefSemaphore);
  1800.    }
  1801.     
  1802.  
  1803. /*
  1804.  * FindNode
  1805.  *
  1806.  * Find a node within a module with a specified name.
  1807.  *
  1808.  * Input
  1809.  *      M = pointer to module node
  1810.  *      S = pointer to string
  1811.  *
  1812.  * Output
  1813.  *      result = NULL if node not found, pointer to node otherwise
  1814.  */
  1815. NodePtr FindNode (M,S)
  1816.    register NodePtr M;
  1817.    StrPtr S;
  1818.    {
  1819.       if (M->NodeType == MODULE)
  1820.      for (M = M->NodeData.NodeMod.FirstChild; M!=NULL; M=M->NodeSib)
  1821.         if (0==StrComp (M->NodeName,S)) return M;
  1822.       return NULL;
  1823.    }
  1824.     
  1825.  
  1826. /*
  1827.  * MakePath
  1828.  *
  1829.  * Make the path list for a given node
  1830.  *
  1831.  * Input
  1832.  *      *N = module node
  1833.  * Output
  1834.  *      *result = path list
  1835.  */
  1836. ListPtr MakePath (N)
  1837.    NodePtr N;
  1838.    {
  1839.       ListPtr P;
  1840.  
  1841.       rsemaphore_enter (NRefSemaphore);
  1842.       P = NULL;
  1843.       while (N->NodeParent != NULL) {
  1844.      NewList (&P,1L);
  1845.      P->Val.Tag = STRING;
  1846.      P->Val.String = CopySPtr (N->NodeName);
  1847.      N = N->NodeParent;
  1848.       }
  1849.       rsemaphore_exit (NRefSemaphore);
  1850.       return P;
  1851.    }
  1852.  
  1853.  
  1854. /*
  1855.  * MakeChild
  1856.  *
  1857.  * Find (or create if necessary) a new child node with a specified name.
  1858.  *
  1859.  * Input
  1860.  *    M = Parent node
  1861.  *    S = name of child
  1862.  *
  1863.  * Output
  1864.  *    N = pointer to child
  1865.  *
  1866.  * A SysError may occur.
  1867.  */
  1868. NodePtr MakeChild  (M,S)
  1869.    NodePtr M;
  1870.    StrPtr S;
  1871.    {
  1872.       register NodePtr N;
  1873.  
  1874.       rsemaphore_enter (NRefSemaphore);
  1875.       N = FindNode (M,S);
  1876.       if (N==NULL) {
  1877.      NewNode (&M->NodeData.NodeMod.FirstChild);
  1878.      if (SysError) {
  1879.         N = NULL;
  1880.         goto exit;
  1881.      }
  1882.      N = M->NodeData.NodeMod.FirstChild;
  1883.      N->NodeParent = M;
  1884.      N->NodeName = CopySPtr (S);
  1885.      N->NodeType = NEWNODE;
  1886.       }
  1887. exit:
  1888.       rsemaphore_exit (NRefSemaphore);
  1889.       return N;
  1890.    }
  1891.  
  1892. /*
  1893.  * Initialize a module node
  1894.  *
  1895.  * Input
  1896.  *      M = pointer to new node
  1897.  */
  1898. void InitModule (M)
  1899.    register NodePtr M;
  1900.    {
  1901.       M->NodeType = MODULE;
  1902.       M->NodeData.NodeMod.FirstChild = NULL;
  1903.       ReadImport (M);
  1904.    }
  1905.  
  1906. /*
  1907.  * MakeNode
  1908.  *
  1909.  * Create all nodes required by a path.
  1910.  *
  1911.  * Input
  1912.  *      Path = pointer to path list
  1913.  *      Type = type to make node if new node
  1914.  * Output
  1915.  *      result = pointer to node specified by path or
  1916.  *               NULL if an error occurred.
  1917.  */
  1918. NodePtr MakeNode (Path,Type)
  1919.    ListPtr Path;
  1920.    int Type;
  1921.    {
  1922.       register NodePtr M;
  1923.       register ListPtr P;
  1924.  
  1925.       rsemaphore_enter (NRefSemaphore);
  1926.       M = RootNode;
  1927.       for (P=Path; P != NULL; P=P->Next)
  1928.      if (P->Val.Tag != STRING) return NULL;
  1929.      else {
  1930.         M = MakeChild (M,P->Val.String);
  1931.         if (M->NodeType == NEWNODE)
  1932.            if (P->Next!=NULL) InitModule (M);
  1933.            else
  1934.           switch (M->NodeType = Type) {
  1935.              case DEF:
  1936.             M->NodeData.NodeDef.DefCode.Tag = BOTTOM;
  1937.             M->NodeData.NodeDef.DefFlags = 0;
  1938.             break;
  1939.              case MODULE:
  1940.             InitModule (M);
  1941.             break;
  1942.           }
  1943.      }
  1944.       rsemaphore_exit (NRefSemaphore);
  1945.       return M;
  1946.    }
  1947.  
  1948.  
  1949. /*
  1950.  * DelImport
  1951.  *
  1952.  * Delete all information affected by the %IMPORT file for a module node
  1953.  * in preparation for rereading the %IMPORT file.
  1954.  *
  1955.  * Input
  1956.  *      M = pointer to module node
  1957.  *
  1958.  * Notes
  1959.  *      IMPORT nodes can be returned to the free list since their
  1960.  *      reference counts are always 1.
  1961.  */
  1962. void DelImport (M)
  1963.    NodePtr M;
  1964.    {
  1965.       register NodePtr *L;
  1966.       register NodePtr N;
  1967.  
  1968.       rsemaphore_enter (NRefSemaphore);
  1969.       for (L = &M->NodeData.NodeMod.FirstChild; (N = *L)!= NULL; )
  1970.  
  1971.      switch (N->NodeType) {
  1972.     
  1973.         case IMPORT:        /* Return IMPORT nodes to free list */
  1974.            DelSPtr (N->NodeName);
  1975.            RepTag (&N->NodeData.NodeImp.ImpDef,BOTTOM);
  1976.            Rot3 ((MetaPtr) &FreeNode, (MetaPtr) L, (MetaPtr) &N->NodeSib);
  1977.            break;
  1978.  
  1979.         case DEF:           /* Delete local function definitions */
  1980.            if (N->NodeData.NodeDef.DefCode.Tag != CODE) 
  1981.           RepTag (&N->NodeData.NodeDef.DefCode,BOTTOM);
  1982.            L = &N->NodeSib;
  1983.            break;
  1984.  
  1985.         case MODULE:
  1986.            L = &N->NodeSib;
  1987.            break;
  1988.  
  1989.         default:
  1990.            printf ("Invalid NodeType in node tree: %d\n",N->NodeType);
  1991.            L = &N->NodeSib;
  1992.            break;
  1993.      }
  1994.       rsemaphore_exit (NRefSemaphore);
  1995.    }
  1996.  
  1997.  
  1998. /*
  1999.  * LinkPath
  2000.  *
  2001.  * Convert a path list to a node if possible.
  2002.  *
  2003.  * Input
  2004.  *      *Def = path list
  2005.  *      Type = NodeType value if new node
  2006.  *
  2007.  * Output
  2008.  *      *Def = node or not changed if error occurs
  2009.  */
  2010. void LinkPath (Path,Type)
  2011.    ObjectPtr Path;
  2012.    int Type;
  2013.    {
  2014.       register NodePtr N;
  2015.  
  2016.       rsemaphore_enter (NRefSemaphore);
  2017.       N = MakeNode (Path->List,Type);
  2018.       if (N != NULL) {
  2019.      RepTag (Path,NODE);
  2020.      Path->Node = CopyNPtr (N);
  2021.       }
  2022.       rsemaphore_exit (NRefSemaphore);
  2023.    }
  2024.  
  2025. /*
  2026.  * SignExtend
  2027.  *
  2028.  * Sign extend a byte.  Not all machines have signed characters.
  2029.  */    
  2030. #define SignExtend(B) ((((B) + 0x80) & 0xFF) - 0x80)
  2031.  
  2032. /*
  2033.  * PrimDef
  2034.  *
  2035.  * Define a primitive function
  2036.  *
  2037.  * Input
  2038.  *      *F = object code for function
  2039.  *      S = name of function
  2040.  *      M = module to put function in
  2041.  *      K = code parameter value
  2042.  *
  2043.  * Output
  2044.  *      result = pointer to node containing function
  2045.  */
  2046. /* VARARGS3 */
  2047. NodePtr PrimDef (F,S,M,K)
  2048.    int (*F) ();
  2049.    char *S;        
  2050.    NodePtr M;
  2051.    char K;
  2052.    {
  2053.       register NodePtr N;
  2054.       StrPtr T;
  2055.       T = MakeString (S);
  2056.       N = MakeChild (M,T);
  2057.       N->NodeType = DEF;
  2058.       N->NodeData.NodeDef.DefCode.Tag = CODE;
  2059.       N->NodeData.NodeDef.DefFlags = 0;
  2060.       N->NodeData.NodeDef.DefCode.Code.CodePtr = F;
  2061.       N->NodeData.NodeDef.DefCode.Code.CodeParam = SignExtend (K);
  2062.       DelSPtr (T);
  2063.       return N;
  2064.    }
  2065.  
  2066.  
  2067. /*
  2068.  * GroupDef
  2069.  *
  2070.  * Define a group of functions
  2071.  *
  2072.  * Input
  2073.  *     T = pointer to table of functions
  2074.  *     N = number entries in table
  2075.  *     M = module node
  2076.  */
  2077. void GroupDef (T,N,M)
  2078.    register OpDef *T;
  2079.    int N;
  2080.    NodePtr M;
  2081.    {
  2082.       while (--N >= 0) 
  2083.      (void) PrimDef (T->OpPtr,T->OpName,M,T->OpParam),
  2084.      T++;
  2085.    }
  2086.  
  2087.  
  2088. /*
  2089.  * Initialize root node and 'sys' subnode.
  2090.  */
  2091. void InitNode ()
  2092.    {
  2093.       register NodePtr R;
  2094.  
  2095.       if (Debug & DebugInit) printf ("enter InitNode\n");
  2096.       RootNode = NULL;
  2097.       NewNode (&RootNode);
  2098.       R = RootNode;
  2099.       R->NodeSib = NULL;
  2100.       R->NodeParent = NULL;
  2101.       R->NodeType = MODULE;
  2102.       R->NodeName = MakeString ("ROOT");
  2103.       R->NodeData.NodeMod.FirstChild = NULL;
  2104.       SysNode = MakeChild (R,MakeString ("sys"));
  2105.       InitModule (SysNode);
  2106.       R = MakeChild (R,MakeString ("math"));
  2107.       InitModule (R);
  2108.       ArithNode = MakeChild (R,MakeString ("arith"));
  2109.       InitModule (ArithNode);
  2110.       LogicNode = MakeChild (R,MakeString ("logic"));
  2111.       InitModule (LogicNode);
  2112.       if (Debug & DebugInit) printf ("exit InitNode\n");
  2113.    }
  2114.  
  2115. /****************************** end of node.c ******************************/
  2116. SHAR_EOF
  2117. if test -f 'interp/node.h'
  2118. then
  2119.     echo shar: over-writing existing file "'interp/node.h'"
  2120. fi
  2121. cat << \SHAR_EOF > 'interp/node.h'
  2122.  
  2123. /****** node.h ********************************************************/
  2124. /**                                                                  **/
  2125. /**                    University of Illinois                        **/
  2126. /**                                                                  **/
  2127. /**                Department of Computer Science                    **/
  2128. /**                                                                  **/
  2129. /**   Tool: IFP                         Version: 0.5                 **/
  2130. /**                                                                  **/
  2131. /**   Author:  Arch D. Robison          Date:   May 1, 1985          **/
  2132. /**                                                                  **/
  2133. /**   Revised by: Arch D. Robison       Date:  July 8, 1986          **/
  2134. /**                                                                  **/
  2135. /**   Principal Investigators: Prof. R. H. Campbell                  **/
  2136. /**                            Prof. W. J. Kubitz                    **/
  2137. /**                                                                  **/
  2138. /**                                                                  **/
  2139. /**------------------------------------------------------------------**/
  2140. /**   (C) Copyright 1987  University of Illinois Board of Trustees   **/
  2141. /**                       All Rights Reserved.                       **/
  2142. /**********************************************************************/
  2143.  
  2144. #ifndef INCLUDE_NODE_H
  2145. #define INCLUDE_NODE_H 1
  2146.  
  2147. /*
  2148.  * Define FETCH as 1 to define "fetch" (^k) functional form, 0 otherwise.
  2149.  * Define XDEF  as 1 to define "xdef"  ({...} f) functional form, 0 otherwise.
  2150.  */
  2151. #define FETCH 0
  2152. #define XDEF 1
  2153.  
  2154. extern ListPtr MakePath ();
  2155. extern NodePtr CopyNPtr (), FindNode ();
  2156. extern NodePtr MakeNode (), MakeChild (), PrimDef ();
  2157. extern NodePtr RootNode, SysNode, ArithNode, LogicNode;
  2158. extern void DelNPtr (), FormPath (), GroupDef (), LinkPath ();
  2159. void InitNode ();
  2160.  
  2161. typedef struct {        /* Used for node initialization tables */
  2162.    char *OpName;
  2163.    char OpParam;
  2164.    int (*OpPtr) ();     /* Actually void, but compiler complains about void */
  2165. } OpDef;                /* in static initializations of this structure      */
  2166.  
  2167. #define OpCount(OpTable) (sizeof(OpTable)/sizeof(OpTable[0])) 
  2168.  
  2169. extern NodePtr FormNode[];
  2170.  
  2171. /*
  2172.  * Subscripts for FormNode
  2173.  *
  2174.  * These must correspond to the entries in the FormOpTable in forms.c
  2175.  */
  2176. #define NODE_C          0
  2177. #define NODE_Comp       1
  2178. #define NODE_Cons       2
  2179. #define NODE_Each       3
  2180. #define NODE_Fetch    4
  2181. #define NODE_Filter     (4 + FETCH)
  2182. #define NODE_If         (5 + FETCH)
  2183. #define NODE_RInsert    (6 + FETCH)
  2184. #define NODE_Out        (7 + FETCH)
  2185. #define NODE_Sel        (8 + FETCH)
  2186. #define NODE_While      (9 + FETCH)
  2187. #define NODE_XDef    (9 + FETCH + XDEF) 
  2188. #define FORM_TABLE_SIZE (10 + FETCH + XDEF)
  2189.  
  2190.  
  2191. typedef struct {
  2192.    NodePtr FormNode;            /* Node pointer for form */
  2193.    char *FormInPrefix;
  2194.    OpDef FormOp;
  2195.    char *FormComment;        /* Comment for `expected' error message */
  2196. } FormEntry;
  2197.  
  2198. extern FormEntry FormTable[FORM_TABLE_SIZE];
  2199.  
  2200. #endif
  2201.  
  2202. /****************************** end of node.h ******************************/
  2203.  
  2204. SHAR_EOF
  2205. #    End of shell archive
  2206. exit 0
  2207.  
  2208. -- 
  2209.  
  2210. Rich $alz            "Anger is an energy"
  2211. Cronus Project, BBN Labs    rsalz@pineapple.bbn.com
  2212. Moderator, comp.sources.unix    sources@uunet.uu.net
  2213.